package com.wxw.BaseLibrary.tool;

import android.util.Log;

import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.*;


/**
 * Created by user on 2016/4/2.
 */
public class ZipUtil {
    //    public static final String ZIP_FILENAME = "C:\\XJPDA.zip";//需要解压缩的文件名
//    public static final String ZIP_DIR = "C:\\XJPDA\\";//需要压缩的文件夹
//    public static final String UN_ZIP_DIR = "C:\\";//要解压的文件目录
    public static final int BUFFER = 1024;//缓存大小

    /**
     * zip压缩功能.
     * 压缩baseDir(文件夹目录)下所有文件，包括子目录
     *
     * @throws Exception
     */
    public static void zipFile(String baseDir, String fileName) throws Exception {
        zipFileList(getSubFiles(new File(baseDir)), fileName);
/*        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(fileName));
        ZipEntry ze = null;
        byte[] buf = new byte[BUFFER];
        int readLen = 0;
        for (int i = 0; i < fileList.size(); i++) {
            File f = (File) fileList.get(i);
            ze = new ZipEntry(getAbsFileName(baseDir, f));
            ze.setSize(f.length());
            ze.setTime(f.lastModified());
            zos.putNextEntry(ze);
            InputStream is = new BufferedInputStream(new FileInputStream(f));
            while ((readLen = is.read(buf, 0, BUFFER)) != -1) {
                zos.write(buf, 0, readLen);
            }
            is.close();
        }
        zos.close();*/
    }

    public static void zipFileNameList(List<String> fileList, String fileName) throws Exception {
        List<File> files = new ArrayList<File>();
        for (String s : fileList) {
            if (!FileUtil.isExists(s)) {
                continue;
            }
            files.add(new File(s));
        }
        zipFileList(files, fileName);
    }

    public static void zipFileList(List<File> fileList, String fileName) throws Exception {
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(fileName));
        zos.setLevel(Deflater.BEST_COMPRESSION);
        ZipEntry ze = null;
        byte[] buf = new byte[BUFFER];
        int readLen = 0;
        for (int i = 0; i < fileList.size(); i++) {
            try {
                File f = fileList.get(i);
                ze = new ZipEntry(f.getName());
                ze.setSize(f.length());
                ze.setTime(f.lastModified());
                InputStream is = new BufferedInputStream(new FileInputStream(f));
                zos.putNextEntry(ze);
                while ((readLen = is.read(buf, 0, BUFFER)) != -1) {
                    zos.write(buf, 0, readLen);
                }
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        zos.close();
    }

    /**
     * 给定根目录，返回另一个文件名的相对路径，用于zip文件中的路径.
     *
     * @param baseDir      java.lang.String 根目录
     * @param realFileName java.io.File 实际的文件名
     * @return 相对文件名
     */
    private static String getAbsFileName(String baseDir, File realFileName) {
        File real = realFileName;
        File base = new File(baseDir);
        String ret = real.getName();
        while (true) {
            real = real.getParentFile();
            if (real == null) {
                break;
            }
            if (real.equals(base)) {
                break;
            } else {
                ret = real.getName() + "/" + ret;
            }
        }
        return ret;
    }

    /**
     * 取得指定目录下的所有文件列表，包括子目录.
     *
     * @param baseDir File 指定的目录
     * @return 包含java.io.File的List
     */
    private static List<File> getSubFiles(File baseDir) {
        List<File> ret = new ArrayList();
        File[] tmp = baseDir.listFiles();
        for (int i = 0; i < tmp.length; i++) {
            if (tmp[i].isFile()) {
                ret.add(tmp[i]);
            }
            if (tmp[i].isDirectory()) {
                ret.addAll(getSubFiles(tmp[i]));
            }
        }
        return ret;
    }

    public static int unZipFile(String zipFile, String folderPath) throws ZipException, IOException {
        return unZipFile(new File(zipFile), folderPath);
    }

    /**
     * 解压缩功能.
     * 将zipFile文件解压到folderPath目录下.
     *
     * @throws Exception
     */
    public static int unZipFile(File zipFile, String folderPath) throws ZipException, IOException {
        //public static void upZipFile() throws Exception{
        ZipFile zfile = new ZipFile(zipFile);
        Enumeration zList = zfile.entries();
        ZipEntry ze = null;
        byte[] buf = new byte[1024];
        while (zList.hasMoreElements()) {
            ze = (ZipEntry) zList.nextElement();
            if (ze.isDirectory()) {
//                Log.d("upZipFile", "ze.getName() = " + ze.getName());
                String dirstr = folderPath + ze.getName();
                //dirstr.trim();
                dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
//                Log.d("upZipFile", "str = " + dirstr);
                File f = new File(dirstr);
                f.mkdir();
                continue;
            }
//            Log.d("upZipFile", "ze.getName() = " + ze.getName());
            OutputStream os = new BufferedOutputStream(new FileOutputStream(getRealFileName(folderPath, ze.getName())));
            InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
            int readLen = 0;
            while ((readLen = is.read(buf, 0, 1024)) != -1) {
                os.write(buf, 0, readLen);
            }
            is.close();
            os.close();
        }
        zfile.close();
//        Log.d("upZipFile", "finishssssssssssssssssssss");
        return 0;
    }

    /**
     * 给定根目录，返回一个相对路径所对应的实际文件名.
     *
     * @param baseDir     指定根目录
     * @param absFileName 相对路径名，来自于ZipEntry中的name
     * @return java.io.File 实际的文件
     */
    private static File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir);
        String substr = null;
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                try {
                    //substr.trim();
                    substr = new String(substr.getBytes("8859_1"), "GB2312");

                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                ret = new File(ret, substr);

            }
//            Log.d("upZipFile", "1ret = " + ret);
            if (!ret.exists()) {
                ret.mkdirs();
            }
            substr = dirs[dirs.length - 1];
            try {
                //substr.trim();
                substr = new String(substr.getBytes("8859_1"), "GB2312");
//                Log.d("upZipFile", "substr = " + substr);
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            ret = new File(ret, substr);
//            Log.d("upZipFile", "2ret = " + ret);
            return ret;
        }
        return ret;
    }
//    复制代码
//    备注： 上面 getRealFileName() 经网友反映可能会有问题，楼下5楼贴出了自己的代码可供参考(未经测试)：
//
//    复制代码
//    public static File getRealFileName(String baseDir, String absFileName)
//    {
//        String[] dirs=absFileName.split("/");
//        String lastDir=baseDir;
//        if(dirs.length>1)
//        {
//            for (int i = 0; i < dirs.length-1;i++)
//            {
//                lastDir +=(dirs[i]+"/");
//                File dir =new File(lastDir);
//                if(!dir.exists())
//                {
//                    dir.mkdirs();
//                    Log.d("getRealFileName", "create dir = "+(lastDir+"/"+dirs[i]));
//                }
//            }
//            File ret = new File(lastDir,dirs[dirs.length-1]);
//            Log.d("upZipFile", "2ret = "+ret);
//            return ret;
//        }
//        else
//        {
//
//            return new File(baseDir,absFileName);
//
//        }
//
//    }
}
